﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Web;
using Microsoft.Practices.Unity;
namespace MvcApplication
{
    public class MyDependencyFactory
    {
        public static void RegisterDependency()
        {

            //Lifetime:这个属性用来控制实例在容器中的生命周期，
            //默认的是TransientLifetimeManager，即每次都请求都会返回一个新的实例；
            //比较常用的是ContainerControlledLifetimeManager，每次请求都会返回同一个实例，即我们平常所说的单例模式。

            string BaseDirectory = AppDomain.CurrentDomain.BaseDirectory;
            if (HttpContext.Current != null)
            {
                BaseDirectory += @"\Bin";
            }
            //获取所有DLL文件路径
            string[] dllPaths = Directory.GetFiles(BaseDirectory, "*.dll", SearchOption.TopDirectoryOnly);
            #region 加载程序集
            List<Assembly> assemblyList = new List<Assembly>();
            foreach (string dllPath in dllPaths)
            {
                try
                {
                    assemblyList.Add(Assembly.LoadFile(dllPath));
                }
                catch (Exception ex)
                {
                    //Log4netHelper<MvcApplication>.Fatal(string.Format("致命错误：加载程序集[{0}]异常", dllPath), ex);
                }
            }
            #endregion
            #region 加载程序集中定义的类型
            List<Type> typeList = new List<Type>();
            foreach (Assembly assembly in assemblyList)
            {
                try
                {
                    typeList.AddRange(assembly.GetTypes().Where(t => t.IsInterface == false));
                }
                catch (Exception ex)
                {
                    //Log4netHelper<MyDependencyFactory1>.Fatal(string.Format("致命错误：获取程序集[{0}]内所有类型时出错！", assembly.GetName().Name), ex);
                }

            }
            //typeList.Where(t => t.FindInterfaces(MyInterfaceFilter, typeof(ISingletonRegister)).Count() > 0);
            //TypeFilter filter = new TypeFilter(MyInterfaceFilter);
            //typeList.Where(t => t.FindInterfaces(filter, typeof(ISingletonRegister)).Count() > 0);
            //实现ISingletonRegister接口的类型集合
            List<Type> iSingletonRegisterTypeList = typeList.Where(t => t.FindInterfaces((a, b) => a.ToString() == b.ToString(), typeof(ISingletonRegister)).Count() > 0).ToList();
            //实现IWeakReferenceRegister接口的类型集合
            List<Type> iWeakReferenceRegisterTypeList = typeList.Where(t => t.FindInterfaces((a, b) => a.ToString() == b.ToString(), typeof(IWeakReferenceRegister)).Count() > 0).ToList();


            #endregion

            //注册ISingletonRegister类型  
            foreach (Type type in iSingletonRegisterTypeList)
            {
                List<Type> implementInterfaceList = type.GetInterfaces().Where(i => i.ToString() != typeof(ISingletonRegister).ToString() && i.ToString() != typeof(IWeakReferenceRegister).ToString()).ToList();
                foreach (Type iType in implementInterfaceList)
                {
                    MyUnityContainer.Current.RegisterType(iType, type, new ContainerControlledLifetimeManager());
                    //MyUnityContainer.Current.RegisterType(iType, t, new ContainerControlledLifetimeManager());//使用频繁，单例  
                    #region =DebugChecker created by lihui 2010707=
                    //if (t.BaseType != typeof(BaseDebugChecker)) continue;
                    //var checker = (BaseDebugChecker)MyUnityContainer.Current.Resolve(iType);
                    //checker.IsDebug();

                    #endregion
                }
            }
            //注册IWeakReferenceRegister类型  
            foreach (Type type in iWeakReferenceRegisterTypeList)
            {
                List<Type> implementInterfaceList = type.GetInterfaces().Where(i => i.ToString() != typeof(ISingletonRegister).ToString() && i.ToString() != typeof(IWeakReferenceRegister).ToString()).ToList();
                foreach (Type iType in implementInterfaceList)
                {
                    MyUnityContainer.Current.RegisterType(iType, type, new ExternallyControlledLifetimeManager());
                    //MyUnityContainer.Current.RegisterType(iType, t, new ContainerControlledLifetimeManager());//使用频繁，单例  
                    #region =DebugChecker created by lihui 2010707=
                    //if (t.BaseType != typeof(BaseDebugChecker)) continue;
                    //var checker = (BaseDebugChecker)MyUnityContainer.Current.Resolve(iType);
                    //checker.IsDebug();

                    #endregion
                }
            }

        }

        public static bool MyInterfaceFilter(Type typeObj, Object criteriaObj)
        {
            return typeObj.ToString() == criteriaObj.ToString();
        }
    }
}
